package com.imooc.ad.index.keyword;

import com.imooc.ad.index.IndexAwre;
import com.imooc.ad.utils.CommonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListSet;

@Slf4j
@Component
/**
 * 倒排索引,keyword(String类型)，value是一个set<Long>集合
 */
public class UnitKeywordIndex implements IndexAwre<String, Set<Long>> {
    private static Map<String, Set<Long>> keywordUnitMap;
    private static Map<Long, Set<String>> unitKeywordMap;

    static {
        keywordUnitMap = new ConcurrentHashMap<>();
        unitKeywordMap = new ConcurrentHashMap<>();
    }

    @Override
    public Set<Long> get(String key) {

        if (StringUtils.isEmpty(key)){
            //返回一个空集合---实际上使用该方法时，key不应该为空
            return Collections.emptySet();
        }

        Set<Long> result = keywordUnitMap.get(key);
        if (result == null){
            return Collections.emptySet();
        }
        return result;
    }

    @Override
    public void add(String key, Set<Long> value) {

        log.info("UnitKeywordIndex, before add: {}",unitKeywordMap);

        Set<Long> unitIdSet = CommonUtils.getorCreate(key,
                                                keywordUnitMap,
                                                ConcurrentSkipListSet::new);
        unitIdSet.addAll(value);

        for (Long unitId : value){
            Set<String> keywordSet = CommonUtils.getorCreate(unitId,
                                                unitKeywordMap,
                                                ConcurrentSkipListSet::new);
        }
        log.info("UnitKeywordIndex, after add: {}",unitKeywordMap);
    }

    @Override
    public void update(String key, Set<Long> value) {
        //更新成本过高，不推荐更新
        log.error("keyword index can not support update");
    }

    @Override
    public void delete(String key, Set<Long> value) {

        log.info("UnitKeywordIndex, before delete: {}",unitKeywordMap);
        //因为可能不是全部删除，仅删除部分关键字，所以先获取
        Set<Long> unitIds = CommonUtils.getorCreate(key,
                                                 keywordUnitMap,
                                                 ConcurrentSkipListSet::new);

        unitIds.removeAll(value);

        for (Long unitId :value){

            Set<String> keywordSet = CommonUtils.getorCreate(unitId,
                    unitKeywordMap,ConcurrentSkipListSet::new);
            keywordSet.remove(key);
        }
        log.info("UnitKeywordIndex, after delete: {}",unitKeywordMap);
    }

    public boolean match(Long unitId, List<String> keywords){
        if (unitKeywordMap.containsKey(unitId)
                 && CollectionUtils.isNotEmpty(unitKeywordMap.get(unitId))){

            Set<String> unitKeyword = unitKeywordMap.get(unitId);
            return CollectionUtils.isSubCollection(keywords, unitKeyword);
        }
        return false;
    }
}
